<template>
    <div class="cmdcfg">
        <el-row>
            <div>
                <exSelect v-model="oper" label="操作类型" :dictList="typeList" size="mini" elstyle="width:120px;min-width:120px"></exSelect>
                <exSwitch label="循环查找" v-model="findRepeat" v-if="oper!='Click'"></exSwitch>
                <span v-if="isMatch">{{isMatch==1?"符合":"不符合"}}</span>
                <span v-if="moveCnt"> 移动次数: {{moveCnt}}</span>
                <span>执行了 {{runIdx}}次</span>
            </div>
            <div class="">
                <exInput v-model="remark" label="备注" width="230" size="mini"></exInput>
                <exInput v-model.number="posdiff" label="偏移量" width="75" size="mini"></exInput>
                <!-- <exSwitch label="像素匹配" v-model="findPix"></exSwitch> -->
            </div>
            <div class="" v-if="oper=='MovePosTwo' || oper=='MovePos'">
                <span  @click="showPoint({x:movex,y:movey})">移动位置:</span>
                <i class="el-icon-d-arrow-right" title="取移动位置" @click="setMovePos"></i>
                <exInput v-model.number="movex" label="x" width="75" size="mini"></exInput>
                <exInput v-model.number="movey" label="y" width="75" size="mini"></exInput>
                <exInput v-model.number="movelimit" label="移动次数" width="75" size="mini"></exInput>
            </div>
            <div class="">
                <span @click="preView()" title="为空时,默认全屏查找">查找范围:</span>
                <i class="el-icon-d-arrow-right" title="取查找范围" @click="setByDevInfo"></i>
                <exInput v-model.number="x1" label="x1" width="75" size="mini"></exInput>
                <exInput v-model.number="y1" label="y1" width="75" size="mini"></exInput>
                <exInput v-model.number="x2" label="x2" width="75" size="mini"></exInput>
                <exInput v-model.number="y2" label="y2" width="75" size="mini"></exInput>
            </div>
            <el-row v-for="(target,targetidx) in targetList" :key="targetidx">
                <div class="">
                    <exInput v-model="target.desc" label="说明" width="55" size="mini"></exInput>
                    <exInput v-model.number="target.iffix" label="误差" width="40" size="mini" title="精度从0-100" :clearable="false"></exInput>
                    <i class="el-icon-d-arrow-right" title="取图片数据" @click="getImgInfo(target)"></i>
                    <i class="el-icon-circle-plus" title="添加一条" @click="addTarget(targetidx)"></i>
                    <i class="el-icon-top" title="上升" @click="movePos(targetidx,1)" ></i>
                    <i class="el-icon-bottom" title="下降" @click="movePos(targetidx,0)" ></i>
                    <i class="el-icon-remove" title="删除" @click="delTarget(targetidx)"></i>

                    <exInput v-model.number="target.rectWidth" label="宽" width="45" size="mini"></exInput>
                    <exInput v-model.number="target.rectHeight" label="高" width="45" size="mini"></exInput>

                    <el-link type="primary" @click="showColors(target)">
                        <!-- 颜色数据({{target.colors.length}}) -->
                        图形:
                        <canvasCmp ref="canvasEl" :colors="target.colors" type="rect" :rectWidth="target.rectWidth" :rectHeight="target.rectHeight"></canvasCmp>
                    </el-link>
                </div>
                <div v-if="target.matchList.length>0" style="word-break: break-all;display:inline-block;max-width:550px;">
                    <template v-for="(item,idx) in target.matchList">
                        <el-link :type="item.waitDeal?'primary':'info'" :key="idx" style="display:inline-block;margin-left:10px;"
                            :title="item.diff"  @click="showPoint(item)">
                            x: {{item.x}} y: {{item.y}}
                        </el-link>
                    </template>
                </div>
            </el-row>
        </el-row>
    </div>
</template>


<script>
import canvasCmp from "./util/canvasCmp.vue"
export default {
    components:{
        canvasCmp
    },
    props: {
        cmdInfo: { type: Object, default: {} },
        devInfo:{ type: Object, default: {} },
        cmdIdx : {},
    },
    data() {
        var targetList =  this.cmdInfo.targetList || [];
        if(targetList.length==0 && this.cmdInfo.rectWidth){
            targetList.push({rectWidth:this.cmdInfo.rectWidth || "",
                rectHeight : this.cmdInfo.rectHeight || "",
                iffix : this.cmdInfo.iffix || 75,
                colors : this.cmdInfo.colors || [],
                matchList: [],
                diff: 0,
                desc : "",
                })
        }
        if(targetList.length==0){
            targetList.push({rectWidth:"",
                rectHeight : "",
                iffix : 75,
                colors : [],
                matchList: [],
                diff: 0,
                desc : "",
                })
        }
        return {
            x1 : this.cmdInfo.x1 || "",
            y1 : this.cmdInfo.y1 || "",
            x2 : this.cmdInfo.x2 || "",
            y2 : this.cmdInfo.y2 || "",
            movex : this.cmdInfo.movex || "",
            movey : this.cmdInfo.movey || "",
            movelimit : this.cmdInfo.movelimit || 0,
            oper : this.cmdInfo.oper || "MovePos",
            remark : this.cmdInfo.remark || "",
            posdiff : this.cmdInfo.posdiff || 0,
            findPix : this.cmdInfo.findPix || false,
            // rectWidth : this.cmdInfo.rectWidth || "",
            // rectHeight : this.cmdInfo.rectHeight || "",
            // iffix : this.cmdInfo.iffix || 65,
            // colors : this.cmdInfo.colors || [],
            // matchList: [],

            targetList: targetList,

            level : this.cmdInfo.level || 0,
            timer : null,
            typeList:[
                {name:"成对定点移动",value:"MovePosTwo"},
                {name:"成对合体",value:"MegerTwo"},
                {name:"定点移动",value:"MovePos"},
                {name:"点击",value:"Click"},
                {name:"仅查找",value:"Find"}
            ],
            isMatch: 0,
            desc: "",
            findRepeat : this.cmdInfo.findRepeat? true: false,
            moveCnt : 0,
            runIdx: 0
        };
    },
    inject: ['doDevCmd','doNextCmd',"getImgData","getImageData","getDevPic","getCurApp","doDevClick"],
    computed:{
        selType(){
            var type = {};
            type = this.typeList.find((item)=>{
                return item.value==this.oper
            })
            type = type || {};
            return type;
        }
    },
    watch:{
        "devInfo.curImg"(){
            if(this.isWaiting){
                this.isWaiting = false;
                this.runCmd();
            }
        }
    },

    mounted() {
    },

    methods: {
        movePos(idx,type){
            if(idx==0 && type==1) return;
            if(idx==this.targetList.length-1 && type==0) return;
            var curtarget = this.targetList.splice(idx,1)[0];
            if(type==2){ //置顶
                this.targetList.splice(0,0,curtarget);
            }else if(type==3){ //置底
                this.targetList.push(curtarget);
            }else if(type==0){ //下降
                this.targetList.splice(idx+1,0,curtarget);
            }else{
                this.targetList.splice(idx-1,0,curtarget);
            }
            this.targetList.push({})
            this.targetList.pop()
        },
        addTarget(idx){
            var item = this.targetList[idx];
            item = JSON.parse(JSON.stringify(item));
            this.targetList.splice(idx,0,item)
        },
        delTarget(idx){
            this.targetList.splice(idx,1);
            
            if(this.targetList.length==0){
                this.targetList.push({rectWidth:"",
                    rectHeight : "",
                    iffix : 75,
                    colors : [],
                    matchList: [],
                    diff: 0,
                    desc : "",
                    })
            }
        },
        getImgInfo(target){
            var rectData = this.getImgData(this.devInfo.clickX,this.devInfo.clickY,
                this.devInfo.clickRX-this.devInfo.clickX,this.devInfo.clickRY-this.devInfo.clickY,true);
            if(rectData.length==0){
                target.colors = this.devInfo.rectcolors ;
                target.rectWidth = this.devInfo.rectcolorswidth ;
                target.rectHeight = this.devInfo.rectcolorsheight ;
                return;
            };

            target.rectWidth = rectData.rectWidth 
            target.rectHeight = rectData.rectHeight;
            target.colors = JSON.parse(JSON.stringify(rectData.rectcolors));
        },
        addSubCmd(){
            this.addCmd({type:"",level:this.level+1},this.cmdIdx+1);
        },
        setByDevInfo(){
            this.x1 = this.devInfo.clickX || "";
            this.y1 = this.devInfo.clickY || "";
            this.x2 = this.devInfo.clickRX || "";
            this.y2 = this.devInfo.clickRY || "";
        },
        setMovePos(){
            this.movex = this.devInfo.clickX;
            this.movey = this.devInfo.clickY
        },
        showColors(targetitem){
            this.devInfo.rectcolors = targetitem.colors;
            this.devInfo.rectcolorswidth = targetitem.rectWidth;
            this.devInfo.rectcolorsheight = targetitem.rectHeight;
        },
        preView(x1,y1,x2,y2){
            if(!x1 && !this.x1) return;
            this.devInfo.clickX = x1 || this.x1;
            this.devInfo.clickY = y1 || this.y1;
            this.devInfo.clickRX = x2 || this.x2;
            this.devInfo.clickRY = y2 || this.y2;
        },
        showPoint(item){
            this.devInfo.clickX = item.x;
            this.devInfo.clickY = item.y;
        },
        saveCmd(){
            this.cmdInfo.oper = this.oper;
            this.cmdInfo.x1 = this.x1;
            this.cmdInfo.y1 = this.y1;
            this.cmdInfo.x2 = this.x2;
            this.cmdInfo.y2 = this.y2;
            this.cmdInfo.movex = this.movex;
            this.cmdInfo.movey = this.movey;
            this.cmdInfo.movelimit = this.movelimit;
            this.cmdInfo.remark = this.remark;
            this.cmdInfo.posdiff = this.posdiff;
            this.cmdInfo.findPix = this.findPix;
            this.cmdInfo.findRepeat = this.findRepeat;
            var list = JSON.parse(JSON.stringify(this.targetList))
            list.map(item=>{
                item.matchList= [];
                item.diff= 0;
            })
            this.cmdInfo.targetList = list;
            
            // this.cmdInfo.rectWidth = this.rectWidth;
            // this.cmdInfo.rectHeight = this.rectHeight;
            // this.cmdInfo.iffix = this.iffix;
            // this.cmdInfo.colors = this.colors;
        },
        initCmd(){
            this.runIdx = 0;
            this.moveCnt =0;
            this.isMatch = 0;
            this.desc = "";
            this.targetList.map(item=>{
                item.matchList = [];
            })
            this.isWaiting = false;
        },
        preCheck(){
            if(this.oper===""){
                this.$message.error("请选择判断类型")
                return false;
            }
            return true;
        },
        runCmd(isOnce){
            if(!this.preCheck()){
                this.runIdx = 0;
                this.$emit("stopRun")
                return;
            }
            this.runIdx ++;
            this.moveCnt =0;
            this.isMatch = 0;
            this.desc = "";
            this.targetList.map(item=>{
                item.matchList = [];
            })
            this.$nextTick(()=>{
                this.doCheck(isOnce)
            })
        },
        doSucc(isOnce){
            if(this.oper!='Click' && this.findRepeat && this.moveCnt>0){
                this.isWaiting = true;
                setTimeout(()=>{
                    this.getDevPic()
                },500)
                return;
            }
            if(this.oper!='Click' && this.matchIdx!=this.targetList.length-1){
                this.matchIdx++;
                this.doCheckRect(isOnce);
                return;
            }
            this.$emit("stopRun")
            this.isMatch = 1;
            if(!isOnce)
                this.doNextCmd({children:true});
        },
        doFail(isOnce){
            if(this.matchIdx!=this.targetList.length-1){
                this.matchIdx++;
                this.doCheckRect(isOnce);
                return;
            }
            this.$emit("stopRun")
            this.isMatch = 2;
            if(!isOnce) this.doNextCmd();
        },
        stopCmd(){
            this.runIdx = 0;
            clearTimeout(this.sTimer);
            this.$emit("stopRun")
        },
        doCheck(isOnce){
            this.isMatch = 0;
            this.desc = "";
            this.matchIdx = 0;
            this.doCheckRect(isOnce);
        },
        doCheckRect(isOnce){
            if(this.findPix){
                this.doCheckRectByPix(isOnce)
                return;
            }
            var that = this;
            // debugger;
            var targetitem = this.targetList[this.matchIdx];
            targetitem.matchList = [];
            var imgx1 = this.x1 || 0;
            var imgy1 = this.y1 || 0;
            var imgx2 = this.x2 || parseInt(this.devInfo.devWidth/this.devInfo.devBet);
            var imgy2 = this.y2 || parseInt(this.devInfo.devHeight/this.devInfo.devBet);
            var srcImg = this.getImageData(imgx1, imgy1, Math.abs(imgx2-imgx1), Math.abs(imgy2-imgy1));
            var rectImg = this.$refs.canvasEl[this.matchIdx].getImgData();
            // var rectImg = that.canvasCtx.getImageData(100, 100, 100, 100);
            var src = cv.matFromImageData(srcImg)
            var templ = cv.matFromImageData(rectImg)
            
            let dst = new cv.Mat();
            let mask = new cv.Mat();
            //参数四：SQDIFF和SQDIFF_NORMED越小数值匹配效果更好，其他方法则反之
            // methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR',  
            //    'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED']  
            //TM_CCOEFF_NORMED  精度在 -1到1之间
            for(var i=0;i<10;i++){
                cv.matchTemplate(src, templ, dst, cv.TM_CCOEFF_NORMED, mask);
                let result = cv.minMaxLoc(dst, mask);
                // console.log(result)
                if(result.maxVal<(targetitem.iffix/100)){
                    break;
                }
                let maxPoint = result.maxLoc;
                var pos = {x:maxPoint.x+imgx1+(targetitem.rectWidth/2)+this.posdiff,y:maxPoint.y+imgy1+(targetitem.rectHeight/2)+this.posdiff,diff:result.maxVal,waitDeal:true};
                if(this.oper=="MovePos"){
                    if(Math.abs(pos.x-this.movex)<20 && Math.abs(pos.y-this.movey)<20){
                        //与移动目标太近,不动
                        pos.waitDeal = false;
                    }
                    targetitem.matchList.push(pos)
                }else{
                    targetitem.matchList.push(pos)
                }
                let color = new cv.Scalar(255, 0, 0, 255);
                let point = new cv.Point(maxPoint.x + templ.cols, maxPoint.y + templ.rows);
                cv.rectangle(src, maxPoint, point, color, -1, cv.LINE_AA, 0);
            }

            src.delete(); dst.delete(); mask.delete();

            if(this.targetList[this.matchIdx].matchList.filter((item)=>{return item.waitDeal?true:false}).length>0){
                // that.desc = "查找成功:"+JSON.stringify(matchList)
                that.doAction(isOnce)
                return;;
            }
            that.doFail(isOnce)
            
        },
        doCheckRectByPix(isOnce){
            var that = this;
            var targetitem = this.targetList[this.matchIdx];
            targetitem.matchList = [];
            var imgx1 = this.x1 || 0;
            var imgy1 = this.y1 || 0;
            var imgx2 = this.x2 || parseInt(this.devInfo.devWidth/this.devInfo.devBet);
            var imgy2 = this.y2 || parseInt(this.devInfo.devHeight/this.devInfo.devBet);

            var checkwidth = imgx2-targetitem.rectWidth;
            var checkheight = imgy2-targetitem.rectHeight;
            for(var j=imgy1;j<checkheight;j++){
                for(var i=imgx1;i<checkwidth;i++){
                    var data = that.getImgData(i,j,targetitem.rectWidth,targetitem.rectHeight,true);
                    var arr = data.rectcolors;
                    // console.log(`x:${i} y:${j}`)
                    // if(i==126 && j==454) debugger;
                    if(arr.length>0){
                        var isBreak = false;
                        var diffcnt = 0;
                        for(var k=0;k<targetitem.colors.length;k++){
                            var coloritem = targetitem.colors[k];
                            for(var l=0;l<coloritem.length;l++){
                                var curPix = arr[k][l];
                                var prePix = coloritem[l];
                                var itemdiff = Math.abs(prePix - curPix);
                                if(itemdiff>targetitem.iffix){
                                    diffcnt++;
                                    if(diffcnt>3){
                                        isBreak = true;
                                        // targetitem.desc = `x:${i} y:${j} 误差:${itemdiff}`
                                        break;
                                    }
                                    
                                }
                            }
                            if(isBreak) break;
                            if(k>20) break;
                        }
                        if(!isBreak){
                            var isadd = true;

                            
                            var pos = {x:i+(targetitem.rectWidth/2)+this.posdiff,
                                        y:j+(targetitem.rectHeight/2)+this.posdiff,
                                        diff:"无",
                                        waitDeal:true};
                            if(this.oper=="MovePos"){
                                if(Math.abs(pos.x-this.movex)<20 && Math.abs(pos.y-this.movey)<20){
                                    //与移动目标太近,不动
                                    pos.waitDeal = false;
                                }
                            }
                            for(var a=0;a<targetitem.matchList.length;a++){
                                var aa = targetitem.matchList[a];
                                if(Math.abs(aa.x-i)<30 && Math.abs(aa.y-j)<30){
                                    isadd = false;
                                    break;
                                }
                            }
                            if(isadd){
                                targetitem.matchList.push(pos)
                            }
                        }
                    }else{
                        that.$message.error("获取画布失败")
                        break;
                    }
                }
            }
            // if(this.targetList[this.matchIdx].matchList.filter((item)=>{return item.waitDeal?true:false}).length>0){
            //     // that.desc = "查找成功:"+JSON.stringify(matchList)
            //     that.doAction(isOnce)
            //     return;;
            // }
            // that.doFail(isOnce)
            
        },
        doAction(isOnce){
            if(this["doAction"+this.selType.value]){
                this["doAction"+this.selType.value].call(this,isOnce);
            }else{
                this.doFail(isOnce);
            }
        },
        getWaitDealList(){
            return this.targetList[this.matchIdx].matchList.filter((item)=>{return item.waitDeal});
        },
        doActionFind(isOnce){
            this.moveCnt = this.moveCnt || 0;
            this.doSucc(isOnce)
        },
        doActionClick(isOnce){
            var list = this.getWaitDealList()
            if(list.length>0){
                var item = list.splice(0,1)[0]
                item.waitDeal = false;
                var sx = parseInt(item.x);
                var sy = parseInt(item.y);
                this.preView(sx,sy)
                this.doDevClick(sx,sy);
                setTimeout(()=>{
                    this.doActionClick(isOnce)
                },300)
            }else{
                this.doSucc(isOnce)
            }
        },
        doActionMovePos(isOnce){
            this.moveCnt = this.moveCnt || 0;
            if(this.movelimit && this.moveCnt>=this.movelimit){
                this.doSucc(isOnce)
                return;
            }
            var list = this.getWaitDealList()
            if(list.length>0){
                var item = list.splice(0,1)[0]
                item.waitDeal = false;
                var sx = parseInt((item.x)*this.devInfo.devBet);
                var sy = parseInt((item.y)*this.devInfo.devBet);
                var ex = parseInt((this.movex)*this.devInfo.devBet);
                var ey = parseInt((this.movey)*this.devInfo.devBet);
                this.preView(item.x,item.y,this.movex,this.movey)
                this.moveCnt++;
                setTimeout(()=>{
                    this.doActionMovePos(isOnce)
                    // this.doSucc(isOnce)
                },600)
                this.doDevCmd(`adb shell input swipe ${sx} ${sy} ${ex} ${ey} 400`);
                
            }else{
                this.doSucc(isOnce)
            }
            
        },
        doActionMovePosTwo(isOnce){
            this.moveCnt = this.moveCnt || 0;
            if(this.movelimit && this.moveCnt>=this.movelimit){
                this.doSucc(isOnce)
                return;
            }
            var list = this.getWaitDealList()
            if(list.length>=2 || this.moveCnt%2==1){
                var item = list.splice(0,1)[0]
                item.waitDeal = false;
                var sx = parseInt((item.x)*this.devInfo.devBet);
                var sy = parseInt((item.y)*this.devInfo.devBet);
                var ex = parseInt((this.movex)*this.devInfo.devBet);
                var ey = parseInt((this.movey)*this.devInfo.devBet);
                this.preView(item.x,item.y,this.movex,this.movey)
                this.moveCnt++;
                setTimeout(()=>{
                    this.doActionMovePosTwo(isOnce)
                },400)
                this.doDevCmd(`adb shell input swipe ${sx} ${sy} ${ex} ${ey} 300`);
                
            }else{
                console.info("end")
                this.doSucc(isOnce)
            }
            
        },
        doActionMegerTwo(isOnce){
            var list = this.getWaitDealList()
            this.moveCnt = this.moveCnt || 0;
            if(list.length>=2){
                var item1 = list.splice(0,1)[0]
                var item2 = list.splice(0,1)[0]
                item1.waitDeal = false;
                item2.waitDeal = false;
                // var sx = parseInt((item1.x+(this.rectWidth/2))*this.devInfo.devBet);
                // var sy = parseInt((item1.y+(this.rectHeight/2))*this.devInfo.devBet);
                // var ex = parseInt((item2.x+(this.rectWidth/2))*this.devInfo.devBet);
                // var ey = parseInt((item2.y+(this.rectHeight/2))*this.devInfo.devBet);
                var sx = parseInt((item1.x)*this.devInfo.devBet);
                var sy = parseInt((item1.y)*this.devInfo.devBet);
                var ex = parseInt((item2.x)*this.devInfo.devBet);
                var ey = parseInt((item2.y)*this.devInfo.devBet);
                this.preView(item1.x,item1.y,item2.x,item2.y)
                this.moveCnt++;
                this.doDevCmd(`adb shell input swipe ${sx} ${sy} ${ex} ${ey} 500`);
                setTimeout(()=>{
                    this.doActionMegerTwo(isOnce)
                },600)
                
            }else{
                this.doSucc(isOnce)
            }
            
        }
        
    }
}
</script>

<style lang="less" scoped>
    .cmdcfg{
        display: inline-block;
    }
</style>
